package asteroids;

import java.util.Random;

/**
 * @author Ewoud
 *
 */
public class Vector {
	
	/**
	 * Creates a new vector with the given x and y value.
	 * 
	 * @param x
	 * @param y
	 */
	public Vector(double x, double y) {
		this.setX(x);
		this.setY(y);
	}
	
	public Vector(Random random) {
		this.setX(random.nextGaussian());
		this.setY(random.nextGaussian());
	}
	
	public double getX() {
		return x;
	}
	
	private void setX(double x) {
		if ( ((Double)x).isNaN() )
			throw new IllegalArgumentException("X value can not be NaN!");
		
		this.x = x;
	}
	
	private double x;

	public double getY() {
		return y;
	}

	private void setY(double y) {
		if ( ((Double)y).isNaN() )
			throw new IllegalArgumentException("Y value can not be NaN!");
		
		this.y = y;
	}
	
	private double y;
	
	// TODO QUESTION: static or not?
	public double getNorm() {
		return Math.sqrt(Math.pow(this.getX(),2) + Math.pow(this.getY(),2));
	}
	
	public static double getNorm(double x, double y) {
		return Math.sqrt(Math.pow(x,2) + Math.pow(y,2));
	}
	
	public double getVectorAngle() {
		return Math.atan2(this.getY(), this.getX());
	}
	
	public static Vector add(Vector v1, Vector v2) {
		return new Vector( v1.getX()+v2.getX() , v1.getY()+v2.getY() );
	}
	
	/**
	 * Add the given amount in the given angle to this vector.
	 * 
	 * @param 	amount
	 * @param	angle
	 * @return	This vector with the given amount added in the given angle.
	 */
	public static Vector add(Vector v, double amount, double angle) {
		return new Vector(v.getX()+amount*Math.cos(angle), v.getY()+amount*Math.sin(angle));
	}
	
	/**
	 * Subtract the first given vector from the second given vector (v2 - v1).
	 * 
	 * @param	v1
	 * @param	v2
	 * @return	The first vector subtracted from the second vector (v2- v1).
	 */
	public static Vector subtract(Vector v1, Vector v2) {
		return new Vector( v2.getX()-v1.getX() , v2.getY()-v1.getY() );
	}
	
	public static double dotProduct(Vector v1, Vector v2){
		return v1.getX()*v2.getX() + v1.getY()*v2.getY();
	}
	
	/**
	 * Scale this vector with the given amount.
	 * 
	 * @param 	amount
	 * @return 	This vector scaled by the given amount
	 */
	public static Vector scale(Vector vector, double amount) {
		return new Vector(vector.getX()*amount, vector.getY()*amount);
	}
}
